package com.be.beadmin.device.impl;

import com.alibaba.excel.util.StringUtils;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.device.dto.input.InspectFileDto;
import com.be.beadmin.device.dto.output.InspectFileEx;
import com.be.beadmin.device.entity.*;
import cn.hutool.core.util.ObjectUtil;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.device.mapper.InspectFileMapper;
import com.be.beadmin.device.mapper.InspectFileMapperEx;
import com.be.beadmin.device.repository.EhsItemRepository;
import com.be.beadmin.device.repository.InspectFileRepository;
import com.be.beadmin.device.repository.InspectItemRepository;
import com.be.beadmin.device.service.InspectFileService;
import com.be.beadmin.project.Util.MinioUtil;
import com.be.beadmin.project.config.MinioConfig;
import com.be.beadmin.project.entity.FileInfo;
import com.be.beadmin.project.entity.Info;
import com.be.beadmin.service.impl.MinioService;
import com.be.beadmin.service.service.SerialNumberService;
import io.minio.MinioClient;
import lombok.RequiredArgsConstructor;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Order;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Min;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @description 服务实现
* @author zty
* @date 2023-10-12
**/
@Service
@RequiredArgsConstructor
public class InspectFileServiceImpl implements InspectFileService {

    @Autowired
    private InspectFileRepository inspectFileRepository;
    @Autowired
    private InspectFileMapper inspectFileMapper;
    @Autowired
    private InspectFileMapperEx inspectFileExMapper;
    @Autowired
    private InspectItemRepository inspectItemRepository;
    @Autowired
    private SerialNumberService serialNumberService;

    MinioUtil minioUtil = new MinioUtil();

    @Override
    public Page<InspectFileEx> getInspectFileByPage(PageEntity pageEntity) {
            Pageable pageable = PageRequest.of(
            pageEntity.getCurrent() -1,
            pageEntity.getPageSize());
            Page<InspectFile> page = inspectFileRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 =   JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(InspectFile_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if(pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(InspectFile_.createTime).as(Date.class)));
                    }
                    return  criteriaBuilder.and(list.toArray(p));
                    }
                    , pageable);
            Page<InspectFileEx> page1 = page.map(inspectFileExMapper::toEntity);
            return page1;

    }

    @Override
    public void addInspectFile(InspectFileDto inspectFileDto) {
            InspectFile result = inspectFileRepository.findInspectFileByIdAndDelete(inspectFileDto.getId(), 0);
            if(ObjectUtil.isNotEmpty(result)) {
                throw new BeadminException("InspectFile不存在,请重新查询");
            }
            InspectFile inspectFile = inspectFileMapper.toEntity(inspectFileDto);
            inspectFileRepository.save(inspectFile);
    }

    @Override
    public void updateInspectFile(InspectFileDto inspectFileDto) {
            InspectFile inspectFile = inspectFileRepository.findInspectFileById(inspectFileDto.getId());
            inspectFile = inspectFileMapper.toEntity(inspectFileDto);
            inspectFileRepository.save(inspectFile);
    }


    @Override
    public void delInspectFile(String id) {
        InspectFile inspectFile = inspectFileRepository.findInspectFileById(id);
        inspectFile.setDelete(1);
        inspectFileRepository.save(inspectFile);
    }

    @Override
    public void delInspectFiles (List<String> ids) { }

    @Override
    public void uploadInspectFile(String inspectitemId, MultipartFile[] multipartFiles, String fileName, String memo, String bucketName) throws Exception {
        InspectItem inspectItem = inspectItemRepository.findInspectItemById(inspectitemId);
        //对文件进行操作
        //文件名
        for(MultipartFile multipartFile:multipartFiles) {
            InspectFile inspectFileDto = new InspectFile();
            if (fileName == null || fileName.equals("")) {
                fileName = multipartFile.getOriginalFilename();
            }
            inspectFileDto.setFileName(fileName);

            //判断同一个项目是否有相同的文件名
            int f = inspectFileRepository.countInspectFilesByFileNameAndItemNameAndDelete(fileName, inspectItem.getItemName(), 0);

            //文件后缀
            String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
            inspectFileDto.setFileExtEndDate(ext);

            String version;
            while (true) {
                version = "v1." + f;
                int num = inspectFileRepository.countEhsFilesByFileNameAndVersionAndDelete(fileName, version, 0);
                if (num == 0) {
                    break;
                } else {
                    f++;
                }
            }
            //System.out.println("version:"+version);
            inspectFileDto.setVersion(version);

            //文件大小
            BigDecimal fileSize = new BigDecimal(multipartFile.getSize());
            inspectFileDto.setFileSize(fileSize);
            //流水号
            //fileInfoDto.setSerialNo(serialNo);
            String fileCode = serialNumberService.getNextSnByCode("FileCode");
            inspectFileDto.setFileCode(fileCode);
            //项目id
            inspectFileDto.setInspectitemId(inspectitemId);
            //项目名称
            inspectFileDto.setItemName(inspectItem.getItemName());
            //检查单号
            inspectFileDto.setTaskId(inspectItem.getTaskId());
            //备注
            inspectFileDto.setMemo(memo);
            //设置bucketName
            inspectFileDto.setBucketName(bucketName);
            //System.out.println(fileInfoDto.toString());
            //处理文件

            String newFileName = fileName.substring(0, fileName.lastIndexOf(".")) + "-" + version + "." + ext;
            String fileUrl = minioUtil.uploadFile3(multipartFile, bucketName, newFileName);
            inspectFileDto.setFileUrl(fileUrl);
            inspectFileDto.setNewFileName(newFileName);
            inspectFileRepository.save(inspectFileDto);
        }
    }

    @Override
    public String previewInspectFile(String inspectitemId)throws Exception{
        InspectFile inspectFile=inspectFileRepository.findInspectFileByIdAndDelete(inspectitemId,0);
        if(ObjectUtil.isEmpty(inspectFile)){
            throw new BeadminException("附件不存在");
        }
        return minioUtil.getPreviewFileUrl(inspectFile.getBucketName(),inspectFile.getNewFileName());
    }

    @Override
    public void downloadInspectFile(String id, HttpServletResponse response)throws Exception{
        InspectFile inspectFile=inspectFileRepository.findInspectFileByIdAndDelete(id,0);
        if(ObjectUtil.isEmpty(inspectFile)){
            throw new BeadminException("附件不存在,请重新查询");
        }
        MinioClient minioClient= MinioConfig.getMinioClient();
        InputStream inputStream=null;
        OutputStream outputStream=null;
        if(StringUtils.isBlank(inspectFile.getNewFileName())){
            response.setHeader("Content-type", "text/html;charset=UTF-8");
            String data = "文件下载失败";
            OutputStream ps = response.getOutputStream();
            ps.write(data.getBytes("UTF-8"));
            return ;
        }
        outputStream = response.getOutputStream();
        inputStream =minioClient.getObject(inspectFile.getBucketName(),inspectFile.getNewFileName());
        byte buf[] = new byte[1024];
        int length = 0;
        response.reset();
        String fileName = URLEncoder.encode(inspectFile.getNewFileName(), "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName);
        response.setContentType("application/octet-stream");
        // 输出文件
        while ((length = inputStream.read(buf)) > 0) {
            outputStream.write(buf, 0, length);
        }
        System.out.println("下载成功");
        inputStream.close();
        outputStream.close();
        if (inputStream != null) {
            inputStream.close();
        }
    }
}